home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / file / managers / mc-3.2 / mc-3 / mc-3.2.1 / xv / xvwidget.c < prev   
Encoding:
C/C++ Source or Header  |  1996-05-17  |  16.7 KB  |  566 lines

  1. /* Widgets for the Midnight Commander - on top of XView panel objects
  2.    Copyright (C) 1995 Jakub Jelinek
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2 of the License, or
  7.    (at your option) any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18.  */
  19.  
  20. #include <config.h>
  21. #include <xview/xview.h>
  22. #include <xview/panel.h>
  23. #include "paneltext.h"
  24.  
  25. #include "dlg.h"
  26. #include "widget.h"
  27. #include "xvmain.h"
  28.  
  29. extern int quote;
  30. extern Dlg_head *midnight_dlg;
  31.  
  32. void xv_widget_layout (Panel_item item, WLay layout);
  33.  
  34. static void xv_button_notify (Panel_item item, Event *event)
  35. {
  36.     WButton *b = (WButton *) xv_get (item, PANEL_CLIENT_DATA);
  37.     Dlg_head *h = (Dlg_head *) xv_get (item, XV_KEY_DATA, KEY_DATA_DLG_HEAD);
  38.     int stop = 0;
  39.     
  40.     if (b->callback)
  41.         stop = (*b->callback) (b->action, b->callback_data);
  42.     if (!b->callback || stop) {
  43.         h->running = 0;
  44.         h->ret_value = b->action;
  45.     }
  46. }
  47.  
  48. int x_create_button (Dlg_head *h, widget_data parent, WButton *b)
  49. {
  50.     Panel_button_item button;
  51.     char buffer [30];
  52.     char *p, *q;
  53.     
  54.     strcpy (buffer, b->text);
  55.     for (p = buffer; *p == ' ' || *p == '['; p++);
  56.     for (q = buffer + strlen (buffer); q > buffer && 
  57.         (!*q || *q == ' ' || *q == ']'); q--);
  58.     *(++q) = 0;
  59.     button = (Panel_button_item) xv_create (
  60.         (Panel) x_get_parent_object ((Widget *) b, parent), PANEL_BUTTON,
  61.         PANEL_LABEL_STRING, p,
  62.         PANEL_NOTIFY_PROC, xv_button_notify,
  63.         PANEL_CLIENT_DATA, b,
  64.         XV_KEY_DATA, KEY_DATA_DLG_HEAD, h,
  65.         NULL);
  66.     b->widget.wdata = (widget_data) button;
  67.     xv_widget_layout (button, b->widget.layout);
  68.     return 1;
  69. }
  70.  
  71. void x_button_set (WButton *b, char *text)
  72. {
  73.     char buffer [30];
  74.     char *p, *q;
  75.     
  76.     strcpy (buffer, b->text);
  77.     for (p = buffer; *p == ' ' || *p == '['; p++);
  78.     for (q = buffer + strlen (buffer); q > buffer && 
  79.         (!*q || *q == ' ' || *q == ']'); q--);
  80.     *(++q) = 0;
  81.     if (b->widget.wdata != (widget_data)NULL)
  82.         xv_set ((Panel_button_item) (b->widget.wdata),
  83.             PANEL_LABEL_STRING, p,
  84.             NULL);
  85. }
  86.  
  87.  
  88. /* Radio button widget */
  89.  
  90. void xv_radio_notify (Panel_item item, int value, Event* event)
  91. {
  92.     WRadio *r = (WRadio *) xv_get (item, PANEL_CLIENT_DATA);
  93.     
  94.     r->pos = r->sel = value;
  95. }
  96.  
  97. int x_create_radio (Dlg_head *h, widget_data parent, WRadio *r)
  98. {
  99.     Panel_choice_item radio;
  100.     int i;
  101.     
  102.     radio = (Panel_choice_item) xv_create (
  103.         (Panel) x_get_parent_object ((Widget *) r, parent), PANEL_CHECK_BOX,
  104.         PANEL_LAYOUT, PANEL_VERTICAL,
  105.         PANEL_CHOOSE_ONE, TRUE,
  106.         PANEL_NOTIFY_PROC, xv_radio_notify,
  107.         PANEL_CLIENT_DATA, r,
  108.         XV_KEY_DATA, KEY_DATA_DLG_HEAD, h,
  109.         NULL);
  110.     for (i = 0; i < r->count; i++)
  111.         xv_set (radio,
  112.             PANEL_CHOICE_STRING, i, r->texts [i],
  113.             NULL);
  114.     xv_set (radio,
  115.         PANEL_VALUE, r->sel,
  116.         NULL);
  117.     r->widget.wdata = (widget_data) radio;
  118.     xv_widget_layout (radio, r->widget.layout);
  119.     return 1;
  120. }
  121.  
  122.  
  123. /* Checkbutton widget */
  124.  
  125. void xv_check_notify (Panel_item item, int value, Event* event)
  126. {
  127.     WCheck *c = (WCheck *) xv_get (item, PANEL_CLIENT_DATA);
  128.     
  129.     c->state = value;
  130. }
  131.  
  132. int x_create_check (Dlg_head *h, widget_data parent, WCheck *c)
  133. {
  134.     Panel_choice_item check;
  135.     
  136.     check = (Panel_choice_item) xv_create (
  137.         (Panel) x_get_parent_object ((Widget *) c, parent), PANEL_CHECK_BOX,
  138.         PANEL_LAYOUT, PANEL_VERTICAL,
  139.         PANEL_CHOOSE_ONE, FALSE,
  140.         PANEL_NOTIFY_PROC, xv_check_notify,
  141.         PANEL_CLIENT_DATA, c,
  142.         PANEL_VALUE, c->state,
  143.         PANEL_CHOICE_STRINGS,
  144.             c->text,
  145.             NULL,
  146.         XV_KEY_DATA, KEY_DATA_DLG_HEAD, h,
  147.         NULL);
  148.     c->widget.wdata = (widget_data) check;
  149.     xv_widget_layout (check, c->widget.layout);
  150.     return 1;
  151. }
  152.  
  153.  
  154. /* Label widget */
  155.  
  156. int x_create_label (Dlg_head *h, widget_data parent, WLabel *l)
  157. {
  158.     Panel_message_item label;
  159.     Panel panel = (Panel) x_get_parent_object ((Widget *) l, parent);
  160.     
  161.     label = (Panel_message_item) xv_create (
  162.         panel, PANEL_MESSAGE,
  163.         PANEL_VALUE_FONT, xv_get (panel, PANEL_BOLD_FONT),
  164.         PANEL_LABEL_FONT, xv_get (panel, PANEL_BOLD_FONT),
  165.         PANEL_LABEL_STRING, l->text,
  166.         PANEL_LINE_BREAK_ACTION, PANEL_WRAP_AT_WORD,
  167.         XV_KEY_DATA, KEY_DATA_DLG_HEAD, h,
  168.         XV_KEY_DATA, KEY_DATA_TILE, panel,
  169.         PANEL_CLIENT_DATA, l,
  170.         NULL);
  171.     l->widget.wdata = (widget_data) label;
  172.     xv_widget_layout (label, l->widget.layout);
  173.     return 1;
  174. }
  175.  
  176. void x_label_set_text (WLabel *label, char *text)
  177. {
  178.     if (label->widget.wdata != (widget_data)NULL) {
  179.         int x, y, w, wold, xi;
  180.         Panel panel = (Panel) xv_get ((Panel_button_item) (label->widget.wdata),
  181.             XV_KEY_DATA, KEY_DATA_TILE);
  182.         
  183.         wold = (int) xv_get ((Panel_button_item) (label->widget.wdata), XV_WIDTH);
  184.         
  185.         xv_set ((Panel_button_item) (label->widget.wdata),
  186.             XV_SHOW, FALSE,
  187.             NULL);
  188.         
  189.         xv_set ((Panel_button_item) (label->widget.wdata),
  190.             PANEL_LABEL_STRING, label->text,
  191.             NULL);
  192.             
  193.         w = (int) xv_get ((Panel_button_item) (label->widget.wdata), XV_WIDTH);
  194.         x = (int) xv_get ((Panel_button_item) (label->widget.wdata), XV_X);
  195.         y = (int) xv_get ((Panel_button_item) (label->widget.wdata), XV_Y);
  196.         
  197.         if (w != wold) {
  198.             Panel_item item;
  199.             
  200.             for (item = (Panel_item) xv_get (panel, PANEL_FIRST_ITEM);
  201.                 item != XV_NULL; 
  202.                 item = (Panel_item) xv_get (item, PANEL_NEXT_ITEM)) {
  203.                 if (xv_get (item, PANEL_ITEM_OWNER))
  204.                     continue;
  205.                 if ((int) xv_get (item, XV_Y) == y) {
  206.                     xi = (int) xv_get (item, XV_X);
  207.                     if (xi > x)
  208.                         xv_set (item,
  209.                             XV_X, xi + w - wold,
  210.                             NULL);
  211.                 }
  212.             }
  213.         }
  214.         xv_set ((Panel_button_item) (label->widget.wdata),
  215.             XV_SHOW, TRUE,
  216.             NULL);
  217.     }
  218. }
  219.  
  220.  
  221.  
  222. /* Gauge widget */
  223.  
  224. int x_create_gauge (Dlg_head *h, widget_data parent, WGauge *g)
  225. {
  226.     Panel_gauge_item gauge;
  227.     Panel panel = (Panel) x_get_parent_object ((Widget *) g, parent);
  228.     
  229.     gauge = (Panel_gauge_item) xv_create (
  230.         panel, PANEL_GAUGE,
  231.         PANEL_DIRECTION, PANEL_HORIZONTAL,
  232.         PANEL_MIN_VALUE, 0,
  233.         PANEL_MAX_VALUE, g->max,
  234.         PANEL_TICKS, 20,
  235.         PANEL_SHOW_RANGE, TRUE,
  236.         PANEL_VALUE, g->current,
  237.         PANEL_GAUGE_WIDTH, 200,
  238.         XV_KEY_DATA, KEY_DATA_DLG_HEAD, h,
  239.         XV_SHOW, g->shown,
  240.         NULL);
  241.     g->widget.wdata = (widget_data) gauge;
  242.     xv_widget_layout (gauge, g->widget.layout);
  243.     return 1;
  244. }
  245.  
  246. void x_gauge_set_value (WGauge *g, int max, int current)
  247. {
  248.     if (g->widget.wdata != (widget_data)NULL) {
  249.         if (max != g->max)
  250.             xv_set ((Panel_gauge_item) (g->widget.wdata),
  251.                 PANEL_VALUE, current,
  252.                 PANEL_MAX_VALUE, max,
  253.                 NULL);
  254.         else
  255.             xv_set ((Panel_gauge_item) (g->widget.wdata),
  256.                 PANEL_VALUE, current,
  257.                 NULL);
  258.     }
  259. }
  260.  
  261. void x_gauge_show (WGauge *g)
  262. {
  263.     if (g->widget.wdata != (widget_data)NULL)
  264.         xv_set ((Panel_gauge_item) (g->widget.wdata),
  265.             XV_SHOW, g->shown,
  266.             NULL);
  267. }
  268.  
  269.  
  270. /* Input widget */
  271.  
  272. static Panel_setting xv_input_notify (Panel_item item, Event *event)
  273. {
  274.     Dlg_head *h = (Dlg_head *) xv_get (item, XV_KEY_DATA, KEY_DATA_DLG_HEAD);
  275.     WInput *in = (WInput *) xv_get (item, PANEL_CLIENT_DATA);
  276.  
  277.     if (h != midnight_dlg) {
  278.         switch (event_action (event)) {
  279.             case ACTION_STOP:
  280.                 h->running = 0;
  281.                 h->ret_value = B_CANCEL;
  282.                return PANEL_NONE;
  283.             default: 
  284.                 switch (event_id (event)) {
  285.                     case '\n':
  286.                     case '\r':
  287.                         if (! event_is_down (event))
  288.                             return PANEL_NONE;
  289.                          h->running = 0;
  290.                          h->ret_value = B_ENTER;
  291.                         return PANEL_NONE;
  292.                 case 27:
  293.                         if (! event_is_down (event))
  294.                             return PANEL_NONE;
  295.                          h->running = 0;
  296.                         h->ret_value = B_CANCEL;
  297.                          return PANEL_NONE;
  298.                      default:
  299.                         return PANEL_INSERT;
  300.                 }
  301.         }
  302.     } else { /* Command line is a special case */
  303.         switch (event_id (event)) {
  304.             case '\n':
  305.             case '\r':
  306.                 if (! event_is_down (event))
  307.                     return PANEL_NONE;
  308.                 send_message (midnight_dlg, (Widget *) in, WIDGET_KEY, '\n');
  309.                 return PANEL_NONE;
  310.             default:
  311.                 return PANEL_INSERT;
  312.         }
  313.     }
  314. }
  315.  
  316. static void xv_input_postnotify (Panel_item item, Event *event, char *buffer,
  317.     int caret_position)
  318. {
  319.     char *p;
  320.     WInput *in = (WInput *) xv_get (item, PANEL_CLIENT_DATA);
  321.  
  322.     p = realloc (in->buffer, strlen (buffer) + in->field_len);
  323.     if (p != (char *) NULL) {
  324.         in->buffer = p;
  325.         strcpy (p, buffer);
  326.         in->current_max_len = strlen (buffer) + in->field_len;
  327.     }
  328.     in->point = caret_position; 
  329. }
  330.  
  331. int x_create_input (Dlg_head *h, widget_data parent, WInput *in)
  332. {
  333.     Panel_text_item input;
  334.     
  335.     input = (Panel_text_item) xv_create (
  336.         (Panel) x_get_parent_object ((Widget *) in, parent), PANELTEXT,
  337.         PANEL_NOTIFY_LEVEL, PANEL_NON_PRINTABLE,
  338.         PANEL_NOTIFY_PROC, xv_input_notify,
  339.         PANEL_CLIENT_DATA, in,
  340.         XV_KEY_DATA, KEY_DATA_DLG_HEAD, h,
  341.         PANEL_VALUE, in->buffer,
  342.         PANEL_VALUE_DISPLAY_LENGTH, in->widget.cols,
  343.         PANEL_VALUE_STORED_LENGTH, 4096,
  344.         PANELTEXT_NOTIFY, xv_input_postnotify,
  345.         NULL);
  346.     in->widget.wdata = (widget_data) input;
  347.     xv_widget_layout (input, in->widget.layout);
  348.     return 1;
  349. }
  350.  
  351.  
  352. /* Listbox widget */
  353.  
  354. void x_listbox_select_nth (WListbox *l, int nth)
  355. {
  356.     if (l->widget.wdata != (widget_data) NULL)
  357.     xv_set ((Panel_list_item) (l->widget.wdata),
  358.             PANEL_LIST_SELECT, nth, TRUE,
  359.             NULL);
  360. }
  361.  
  362. void x_listbox_delete_nth (WListbox *l, int nth)
  363. {
  364.     xv_set ((Panel_list_item) (l->widget.wdata),
  365.         PANEL_LIST_DELETE, l->pos,
  366.         NULL);
  367. }
  368.  
  369. static void xv_listbox_notify (Panel_item item, char *string, 
  370.     caddr_t client_data, Panel_list_op op, Event *event)
  371. {
  372.     WListbox *l = (WListbox *) xv_get (item, PANEL_CLIENT_DATA);
  373.     Dlg_head *h = (Dlg_head *) xv_get (item, XV_KEY_DATA, KEY_DATA_DLG_HEAD);
  374.  
  375.     if (op == PANEL_LIST_OP_SELECT || op == PANEL_LIST_OP_DBL_CLICK) {
  376.         int i;
  377.         WLEntry *e;
  378.         
  379.         l->current = (WLEntry *) client_data;
  380.         for (i = 0, e = l->list; i < l->count; i++, e = e->next)
  381.             if (e == l->current) {
  382.                 l->pos = i;
  383.                 break;
  384.             }
  385.     }
  386.     if (op == PANEL_LIST_OP_DBL_CLICK) {
  387.         h->running = 0;
  388.         h->ret_value = B_ENTER;
  389.     }
  390. }
  391.  
  392. int x_create_listbox (Dlg_head *h, widget_data parent, WListbox *l)
  393. {
  394.     Panel_list_item listbox;
  395.     WLEntry *e;
  396.     int i;
  397.     
  398.     listbox = (Panel_list_item) xv_create (
  399.         (Panel) x_get_parent_object ((Widget *) l, parent), PANEL_LIST,
  400.         PANEL_NOTIFY_PROC, xv_listbox_notify,
  401.         PANEL_CLIENT_DATA, l,
  402.         XV_KEY_DATA, KEY_DATA_DLG_HEAD, h,
  403.         PANEL_CHOOSE_ONE, TRUE,
  404.         PANEL_LIST_DISPLAY_ROWS, l->widget.lines,
  405.         PANEL_LIST_DO_DBL_CLICK, TRUE,
  406.         NULL);
  407.     l->widget.wdata = (widget_data) listbox;
  408.     /* The user could add some entries even before this stuff gets displayed */
  409.     e = l->list; i = 0;
  410.     if (e != NULL)
  411.         do {
  412.             xv_set (listbox,
  413.                 PANEL_LIST_INSERT, i,
  414.                 PANEL_LIST_STRING, i, e->text,
  415.                 PANEL_LIST_CLIENT_DATA, i, e,
  416.             NULL);
  417.             if (e == l->current)
  418.                 x_listbox_select_nth (l, i);
  419.             e = e->next;
  420.             i++;
  421.         } while (e != l->list);
  422.     xv_widget_layout (listbox, l->widget.layout);
  423.     return 1;
  424. }
  425.  
  426. void x_list_insert (WListbox *l, WLEntry *p, WLEntry *e)
  427. {
  428.     int i;
  429.  
  430.     if (l->widget.wdata == (widget_data) NULL)
  431.         return;
  432.  
  433.     /* Jakub, shouldn't we have an i++ here? */
  434.     for (i = 0; p != NULL && p != e; e = e->next, i++)
  435.     ;
  436.  
  437.     xv_set ((Panel_list_item) (l->widget.wdata),
  438.     PANEL_LIST_INSERT, i,
  439.         PANEL_LIST_STRING, i, e->text,
  440.         PANEL_LIST_CLIENT_DATA, i, e,
  441.         NULL);
  442. }
  443.  
  444. static void xv_buttonbar_notify (Panel_item item, Event *event)
  445. {
  446.     WButtonBar *bb = (WButtonBar *) xv_get (item, PANEL_CLIENT_DATA);
  447.     int idx = xv_get (item, XV_KEY_DATA, KEY_DATA_BUTTONBAR_IDX);
  448.     
  449.     if (bb->labels [idx - 1].function)
  450.         xv_post_proc (midnight_dlg, *bb->labels [idx - 1].function, 
  451.             bb->labels [idx - 1].data);
  452. }
  453.  
  454. extern Menu MenuBar [];
  455.  
  456. static Menu xv_create_buttonbarmenu (void)
  457. {
  458.     return xv_create (XV_NULL, MENU,
  459.         MENU_ITEM,
  460.             MENU_STRING, "Panel",
  461.             MENU_PULLRIGHT, MenuBar [0],
  462.             NULL,
  463.         MENU_ITEM,
  464.             MENU_STRING, "File",
  465.             MENU_PULLRIGHT, MenuBar [1],
  466.             NULL,
  467.         MENU_ITEM,
  468.             MENU_STRING, "Command",
  469.             MENU_PULLRIGHT, MenuBar [2],
  470.             NULL,
  471.         MENU_ITEM,
  472.             MENU_STRING, "Options",
  473.             MENU_PULLRIGHT, MenuBar [3],
  474.             NULL,
  475.         NULL);
  476. }
  477.  
  478. int x_create_buttonbar (Dlg_head *h, widget_data parent, WButtonBar *bb)
  479. {
  480.     Panel_button_item button;
  481.     Panel panel = (Panel) x_get_parent_object ((Widget *) bb, parent);
  482.     int i;
  483.  
  484.     for (i = 1; i <= 10; i++) {
  485.         button = xv_create (panel, PANEL_BUTTON,
  486.             PANEL_LABEL_STRING, bb->labels [i - 1].text,
  487.             PANEL_CLIENT_DATA, bb,
  488.             XV_KEY_DATA, KEY_DATA_BUTTONBAR_IDX, i,
  489.         NULL);
  490.         if (bb->labels [i - 1].text && 
  491.             !strcmp (bb->labels [i - 1].text, "PullDn")) {
  492.             xv_set (button,
  493.                 PANEL_ITEM_MENU, xv_create_buttonbarmenu (),
  494.                 NULL);
  495.         } else {
  496.             xv_set (button,
  497.                 PANEL_NOTIFY_PROC, xv_buttonbar_notify,
  498.                 NULL);
  499.         }
  500.         if (i == 1)
  501.             xv_set (button,
  502.                 XV_X, 4,
  503.                 NULL);
  504.     }
  505.     xv_set (panel, 
  506.         XV_KEY_DATA, KEY_DATA_PANEL_CONTAINER, xv_get (panel, XV_OWNER),
  507.         NULL);
  508.     bb->widget.wdata = (widget_data) panel;
  509.     return 1;
  510. }
  511.  
  512. void x_redefine_label (WButtonBar *bb, int idx)
  513. {
  514.     Panel_item ip;
  515.     int i, j, x;
  516.     Panel_item items [10];
  517.     Panel panel = (Panel) bb->widget.wdata;
  518.     Menu menu;
  519.  
  520.     for (i = 0; i < 10; i++)
  521.         items [i] = XV_NULL;
  522.     if (panel != XV_NULL) {
  523.         PANEL_EACH_ITEM (panel, ip)
  524.             if ((WButtonBar *) xv_get (ip, PANEL_CLIENT_DATA) == bb) {
  525.                 i = xv_get (ip, XV_KEY_DATA, KEY_DATA_BUTTONBAR_IDX);
  526.                 if (i == idx) {
  527.                     xv_set (ip,
  528.                         PANEL_LABEL_STRING, bb->labels [idx - 1].text,
  529.                         NULL);
  530.                     if (bb->labels [idx - 1].text && 
  531.                         !strcmp (bb->labels [idx - 1].text, "PullDn")) {
  532.                         if (xv_get (ip, PANEL_ITEM_MENU) == XV_NULL)
  533.                             xv_set (ip,
  534.                                 PANEL_NOTIFY_PROC, NULL,
  535.                                 PANEL_ITEM_MENU, xv_create_buttonbarmenu (),
  536.                                 NULL);
  537.                 } else {
  538.                     if ((menu = xv_get (ip, PANEL_ITEM_MENU)) != XV_NULL)
  539.                         xv_set (ip,
  540.                                 PANEL_NOTIFY_PROC, xv_buttonbar_notify,
  541.                                 PANEL_ITEM_MENU, XV_NULL,
  542.                                 NULL);
  543.                             xv_destroy_safe (menu);
  544.                     }
  545.                 }
  546.                 items [i - 1] = ip;
  547.             }
  548.         PANEL_END_EACH
  549.         j = xv_get (panel, PANEL_ITEM_X_GAP);
  550.         for (i = 0, x = 4; i < 10; i++) {
  551.             xv_set (items [i],
  552.                 XV_X, x,
  553.                 NULL);
  554.             x += j + xv_get (items [i], XV_WIDTH);
  555.         }
  556.     }
  557. }
  558.  
  559. /* returns 1 if bb is in another panel container than paneletc (panel, tree,
  560.  * info, view, etc. */
  561. int x_find_buttonbar_check (WButtonBar *bb, Widget *paneletc)
  562. {
  563.     return (bb->widget.wcontainer != paneletc->wcontainer);
  564. }
  565.  
  566.